#include <gpiod.h>  // 包含libgpiod库的头文件
#include <stdio.h>  // 包含标准输入输出库
#include <unistd.h> // 包含UNIX标准库，用于usleep函数
#include <sys/types.h>
#include <alsa/asoundlib.h>
#include <stdbool.h>
#include "record.h"
#include "control.h"


#define GPIO_LINE 9 // 定义GPIO线的编号，这里是PF9
#define VOLUME_UP_LINE 8 // 音量加按键连接到GPIOF线8
#define VOLUME_DOWN_LINE 7 // 音量减按键连接到GPIOF线7

// 录音相关变量
    snd_pcm_t *capture = NULL;
    snd_pcm_uframes_t period;
    char *buffer = NULL;
    FILE *pcm_file = NULL;
    int recording = 0;

    // 音量设置相关变量
    long volume = 0; // 初始音量
    long volume_step = 10; // 每次调整的音量步长

// 录音开始函数
void start_recording()
{
    capture = record_start("hw:0,1", SND_PCM_FORMAT_S16_LE, 2, 44100, &period);
    if (!capture)
    {
        fprintf(stderr, "Failed to start recording\n");
        return;
    }

    buffer = (char *)malloc(snd_pcm_frames_to_bytes(capture, period));
    if (!buffer)
    {
        perror("malloc");
        record_stop(capture);
        capture = NULL;
        return;
    }

    pcm_file = fopen("output.pcm", "wb");
    if (!pcm_file)
    {
        perror("Error opening output file");
        free(buffer);
        record_stop(capture);
        capture = NULL;
        return;
    }

    recording = 1;
    printf("Recording started\n");
}

// 录音停止函数
void stop_recording()
{
    if (recording && capture)
    {
        recording = 0;

        free(buffer);
        buffer = NULL;

        fclose(pcm_file);
        pcm_file = NULL;

        record_stop(capture);
        capture = NULL;

        printf("Recording stopped\n");
    }
}

int main(void)
{
    // 按键引脚相关变量
    struct gpiod_chip *chip; // 定义指向GPIO芯片的指针
    struct gpiod_line *line; // 定义指向GPIO线的指针
    struct gpiod_line *volume_up;
    struct gpiod_line *volume_down;
    int value, last_value;   // 定义当前值和上一次的值，用于检测状态变化
    int value_up, last_value_up;
    int value_down, last_value_down;

    // 打开GPIO芯片
    chip = gpiod_chip_open_by_label("GPIOF");
    if (!chip)
    {
        perror("打开GPIO芯片失败");
        return 1;
    }

    // 获取GPIO线
    line = gpiod_chip_get_line(chip, GPIO_LINE);
    if (!line)
    {
        perror("获取GPIO线失败");
        gpiod_chip_close(chip);
        return 1;
    }

    volume_up = gpiod_chip_get_line(chip, VOLUME_UP_LINE);
    if (!volume_up)
    {
        perror("获取GPIO线失败");
        gpiod_chip_close(chip);
        return 1;
    }

    volume_down = gpiod_chip_get_line(chip, VOLUME_DOWN_LINE);
    if (!volume_down)
    {
        perror("获取GPIO线失败");
        gpiod_chip_close(chip);
        return 1;
    }

    // 将GPIO线设置为输入模式
    if (gpiod_line_request_input(line, "key1"))
    {
        perror("请求将GPIO线设置为输入模式失败");
        gpiod_chip_close(chip);
        return 1;
    }

    if (gpiod_line_request_input(volume_up, "key3"))
    {
        perror("请求将GPIO线设置为输入模式失败");
        gpiod_chip_close(chip);
        return 1;
    }

    if (gpiod_line_request_input(volume_down, "key2"))
    {
        perror("请求将GPIO线设置为输入模式失败");
        gpiod_chip_close(chip);
        return 1;
    }

    // 获取初始的GPIO线值
    last_value = gpiod_line_get_value(line);
    last_value_up = gpiod_line_get_value(volume_up);
    last_value_down = gpiod_line_get_value(volume_down);

    // 无限循环检测GPIO线值的变化
    while (1)
    {
        // 获取当前的GPIO线值
        value = gpiod_line_get_value(line);
        value_up = gpiod_line_get_value(volume_up);
        value_down = gpiod_line_get_value(volume_down);

        // 如果当前值与上一次的值不同，说明按键状态发生了变化
        if (value != last_value)
        {
            // 如果当前值为0，表示按键被按下
            if (value == 0)
            {
                printf("key1 pressed\n");
                start_recording();
            }
            // 如果当前值为1，表示按键被释放
            else
            {
                printf("key1 released\n");
                stop_recording();
            }

            // 更新上一次的值为当前值
            last_value = value;
        }

        if (value_up != last_value_up)
        {
            if (value_up == 0)
            {
                printf("key3 pressed\n");
                volume = get_playback_volume("hw:0", "Analog");
                set_playback_volume("hw:0", "Analog", volume + volume_step);
                printf("当前音量：%ld\n", volume + volume_step);
            }
            else
            {
                printf("key3 released\n");
                
            }

            last_value_up = value_up;
        }

        if (value_down != last_value_down)
        {
            if (value_down == 0)
            {
                printf("key2 pressed\n");
                volume = get_playback_volume("hw:0", "Analog");
                set_playback_volume("hw:0", "Analog", volume - volume_step);
                printf("当前音量：%ld\n", volume - volume_step);
            }
            else
            {
                printf("key2 released\n");
                
            }

            last_value_down = value_down;
        }

        // 如果正在录音，继续写入数据
        if (recording)
        {
            snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period);
            if (frames < 0)
            {
                if (frames == -EPIPE)
                {
                    fprintf(stderr, "XRUN.\n");
                    snd_pcm_prepare(capture);
                }
                else
                {
                    fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
                }
            }
            else
            {
                fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file);
            }
        }

        // 延时100毫秒，防止检测过于频繁
        //usleep(100000);
    }

    // 关闭GPIO芯片
    gpiod_chip_close(chip);
    return 0;
}